<?php

if( !defined( 'IN_INU' ) )
{
	return;
}

/**
 * 支付平台调用接口
 * 使用方法
 * $payClient = & FM_Pay::init();
 * $payClient->getUser( $uId );
 * $payClient->buy();
 *
 */
class FM_Pay
{
	protected $serverAddr;
	protected $appId;
	protected $timeout = 5;
	
	/**
	 * 获取FM_Pay实例
	 *
	 * @return FM_Pay
	 */
	public static function init()
	{
		static $apiClient = null;
		if( empty( $apiClient ) )
			$apiClient = new FM_Pay();
		
		return $apiClient;
	}
	
	private function __construct()
	{
		$config = & Common::getConfig();
		$this->appId = $config['api']['appId'];
		$this->serverAddr = $config['paymentServer']['url'] . "?gameId={$this->appId}";
		if( isset( $config['paymentServer']['timeout'] ) )
		{
			$this->timeout = $config['paymentServer']['timeout'];
		}
	}
	
	/**
	 * 获取用户信息
	 *
	 * @param Int $uId
	 * @return Array
	 */
	public function getUser( $uId )
	{
		return $this->callMethod( 'user.getUser' , array( 'userId' => $uId ) );
	}
	
	/**
	 * 扣币
	 *
	 * @param Int $uId	//用户ID
	 * @param Int $amount	//扣币金额
	 * @param Int $goodsId	//商品ID
	 * @param String $desc	//描述
	 * @return Array
	 */
	public function buy( $uId , $amount , $goodsId , $desc = null )
	{
		$params = array
		(
			'userId' => $uId , 
			'amount' => $amount ,
			'gameId' => $this->appId ,
			'goodsId' => $goodsId , 
			'desc' => $desc ,
		);
		return $this->callMethod( 'user.buy' ,  $params );
	}
	
	/**
	 * 获取消费日志
	 *
	 * @param Int $uId
	 * @param Int $year
	 * @param Int $month
	 * @return Array
	 */
	public function getLog( $uId , $year , $month )
	{
		return $this->callMethod( 'log.getLog' , array( 'userId' => $uId , 'year' => $year , 'month' => $month ) );
	}
	
	/**
	 * 获取订单日志
	 *
	 * @param Int $uId
	 * @param Int $year
	 * @param Int $month
	 * @param Int $status
	 * @return Array
	 */
	public function getOrderLog( $uId , $year , $month , $status )
	{
		return $this->callMethod( 'order.getLog' , array( 'userId' => $uId ,'year' => $year , 'month' => $month  , 'status'=> $status ) );
	}
	
	/**
	 * 生成订单
	 *
	 * @param Int $uId	//用户id
	 * @param Int $paymentType	//支付类型
	 * @param Int $amount	//金额
	 * @param Int $fb	//订单完成后，用户获得的F币数量
	 * @param Int $receiver	//好友id
	 * @return Array
	 * @modifer	Luckyboys	2009-12-15	增加Fb参数
	 */
	public function createOrder( $uId , $paymentType , $amount , $fb , $receiver = 0 )
	{
		
		return $this->callMethod( 'order.createOrder' , array( 'userId' => $uId , 'paymentType' => $paymentType , 'amount' => $amount , 'fb' => $fb , 'gameId' => $this->appId , 'receiver' => $receiver ) );
	}
	
	/**
	 * 生成一个特殊订单，金额为0，完成时再修改金额
	 *
	 * @param Int $uId	//用户id
	 * @param Int $paymentType	//支付类型	 	 
	 * @param Int $receiver	//好友id
	 * @return int	 
	 */
	public function markOrder( $uId , $paymentType , $receiver = 0 )
	{
		return $this->callMethod( 'order.createMarkOrder' , array( 'userId' => $uId , 'paymentType' => $paymentType , 'gameId' => $this->appId , 'receiver' => $receiver ) );
	}
	
	/**
	 * 完成一个特殊订单，将金额0修改成实际值
	 *
	 * @param Int $orderId	//订单ID
	 * @param float $amount	//订单金额	 	 
	 * @param Int $fb	//订单完成后，用户获得的F币数量
	 * @return bool	 
	 */
	public function unmarkOrder( $orderId , $amount , $fb )
	{
		return $this->callMethod( 'order.unmarkOrder' , array( 'orderId' => $orderId , 'amount' => $amount , 'fb' => $fb ) );
	}
	
	/**
	 * 根据订单ID来获取订单
	 *
	 * @param Int $orderId  订单ID
	 * @return Array(
	 *			  orderId:int	 //订单Id
	 *			  amount:float	//订单金额
	 *			  userId:int	  //用户ID
	 *			  gameId:int	  //游戏ID
	 *			  paymentType:int //支付网关类型：0 => 未知支付网关类型；1 => Offerpal支付网关；2 => Paypal支付网关
	 *			  transactionId:int   //第三方支付网关的事务订单ID
	 *			  status:int	  //状态值：0 => 订单创建状态；1 => 冻结订单状态；2 => 取消订单状态；3 => 完成订单状态；4 => 坏帐订单状态
	 *			  whoPay:int	  //谁为该用户付款
	 *			  recoveryCredit:float	//当出现坏帐时，最终回收了的金额数
	 *			  createOrderTime:int	 //订单创建时间
	 *			  updateTime:int	  //最后更新状态时间
	 *		  )
	 */
	public function getOrderByOrderId( $orderId )
	{
		return $this->callMethod( 'order.getOrderByOrderId' , array( 'orderId' => $orderId ) );
	}
	
	/**
	 * 完成订单
	 *
	 * @param Int $orderId
	 * @return Array
	 */
	public function completeOrder( $orderId )
	{
		return $this->callMethod( 'order.complete' , array( 'orderId' => $orderId ) );
	}
	
	/**
	 * 根据第三方支付网关的事务订单ID获取订单
	 *
	 * @param int $transactionId  第三方支付网关的事务订单ID
	 * @param int $paymentType	支付网关类型：0 => 未知支付网关类型；1 => Offerpal支付网关；2 => Paypal支付网关；9 =>Crzyfish支付网关
	 * @return Array(
	 *			  orderId:int	 //订单Id
	 *			  amount:float	//订单金额
	 *			  userId:int	  //用户ID
	 *			  gameId:int	  //游戏ID
	 *			  paymentType:int //支付网关类型：0 => 未知支付网关类型；1 => Offerpal支付网关；2 => Paypal支付网关
	 *			  transactionId:int   //第三方支付网关的事务订单ID
	 *			  status:int	  //状态值：0 => 订单创建状态；1 => 冻结订单状态；2 => 取消订单状态；3 => 完成订单状态；4 => 坏帐订单状态
	 *			  whoPay:int	  //谁为该用户付款
	 *			  recoveryCredit:float	//当出现坏帐时，最终回收了的金额数
	 *			  createOrderTime:int	 //订单创建时间
	 *			  updateTime:int	  //最后更新状态时间
	 *		  )
	 */
	public function getOrderByTransactionId( $transactionId , $paymentType )
	{
		return $this->callMethod( 'order.getOrderByTransactionId' , array( 'transactionId' => $transactionId , "paymentType" => $paymentType ) );
	}
	
	/**
	 * 查看一个第三方支付网关的事务订单ID是否被绑定过
	 * @param int $transactionId  第三方支付网关的事务订单ID
	 * @param int $paymentType	支付网关类型：0 => 未知支付网关类型；1 => Offerpal支付网关；2 => Paypal支付网关
	 * @return  boolean
	 */
	public function orderIsBindedTransactionId( $transactionId , $paymentType )
	{
		return $this->callMethod( 'order.isBindedTransactionId' , array( 'transactionId' => $transactionId , "paymentType" => $paymentType ) );
	}
	
	/**
	 * 把订单绑定第三方支付网关的事务订单ID
	 * @param Int $orderId  订单ID
	 * @param int $transactionId  第三方支付网关的事务订单ID
	 * @param int $paymentType	支付网关类型：0 => 未知支付网关类型；1 => Offerpal支付网关；2 => Paypal支付网关；9 => Crzyfish支付网关 
	 * @return  boolean
	 */
	public function orderBindTransactionId( $orderId , $transactionId , $paymentType )
	{
		return $this->callMethod( 'order.bindTransactionId' , array( "orderId" => $orderId , 'transactionId' => $transactionId , "paymentType" => $paymentType ) );
	}
	
	/**
	 * 延长会员有效期
	 *
	 * @param Int $uId
	 * @param Int $number
	 * @return Array
	 */
	public function prolongVip( $uId , $number )
	{
		return $this->callMethod( 'vip.prolong' , array( 'userId' => $uId , 'number' => $number ) );
	}
	
	/**
	 * 订单复查
	 *
	 * @param Int $uId
	 * @param Int $orderId	//复查涉及订单
	 * @param Int $desc	//复查描述
	 * @return Array
	 */
	public function recheckOrder( $uId , $orderId , $desc = null )
	{
		return $this->callMethod( 'userSupport.recheckOrder' , array( 'userId' => $uId , 'orderId' => $orderId , 'desc' => $desc ) );
	}
	
	private function callMethod( $method , $params )
	{
		$data = $this->post_request( $method , $params );
		$result = json_decode( $data, true );
		if ( !is_array( $result ) )
		{
			throw new Exception( 'Server Error' , 1000 );
		}
			
		if( !empty( $result['code'] ) )
		{
			throw new Exception( $result['desc'] , $result['code'] );
		}
			
		return $result;
	}
	
	private function post_request( $method , $params )
	{
		$post_string = $this->create_post_string( $method , $params );
		$useragent = 'FMPay API PHP5 Client 1.0 (curl) ' . phpversion();
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $this->serverAddr );
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string );
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
		curl_setopt($ch, CURLOPT_USERAGENT, $useragent );
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout );
		curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout );
		$result = curl_exec( $ch );
		curl_close($ch);
		return $result;
	}
	
	private function create_post_string($method, $params) 
	{
		$post_params = array();
		foreach ($params as $key => &$val) {
			$post_params[] = $key.'='.urlencode($val);
		}
		return "method={$method}&" . implode('&', $post_params );
	}
}